package com.sailfish.springbootdemo.service.db2.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sailfish.springbootdemo.common.DB2Config;
import com.sailfish.springbootdemo.configs.UserHeaderHolder;
import com.sailfish.springbootdemo.dao.db2.*;
import com.sailfish.springbootdemo.dao.db4.UserDao;
import com.sailfish.springbootdemo.pojo.Result;
import com.sailfish.springbootdemo.pojo.db2.*;
import com.sailfish.springbootdemo.pojo.db4.Operate;
import com.sailfish.springbootdemo.pojo.db4.OperateLog;
import com.sailfish.springbootdemo.pojo.db4.User;
import com.sailfish.springbootdemo.service.db2.PcbMaterialService;
import com.sailfish.springbootdemo.service.db2.PcbParentFactoryInfoService;
import com.sailfish.springbootdemo.service.db4.OperateLogService;
import com.sailfish.springbootdemo.service.db4.OperateService;
import com.sailfish.springbootdemo.utils.ResultUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class PcbMaterialServiceImpl implements PcbMaterialService {

//    @Autowired
//    PcbMaterialDao pcbMaterialDao;

    @Value("${personal.config.file.file-save-url}")
    String rootPath;
    @Autowired
    PcbMaterialLibraryDao pcbMaterialLibraryDao;
    @Autowired
    PcbMaterialParamDao pcbMaterialParamDao;
    @Autowired
    PcbMaterialFileDao pcbMaterialFileDao;
    @Autowired
    PcbMaterialFactoryDao pcbMaterialFactoryDao;
    @Autowired
    PcbSonFactoryInfoDao pcbSonFactoryInfoDao;
    @Autowired
    PcbParentFactoryInfoService pcbParentFactoryInfoService;
    @Autowired
    PcbMaterialLibraryAndFactoryDao pcbMaterialLibraryAndFactoryDao;
    @Autowired
    UserDao userDao;
    @Autowired
    PcbApproveProcessDao approveProcessDao;
    @Autowired
    OperateService operateService;
    @Autowired
    OperateLogService operateLogService;

    @Override
    public List<PcbMaterialParam> getAllPcbMaterialParam(PcbMaterialParam param) {
        return pcbMaterialParamDao.getAllByLimit(param);
    }

    @Transactional(transactionManager = "MysqlTransactionManager2")
    @Override
    public Result insertOrUpdatePcbMaterialParam(PcbMaterialParam param) {
        try {
            String userId = UserHeaderHolder.getUserId();
            if (param.getPcbMaterialParamId() == null) {
                PcbMaterialParam search = new PcbMaterialParam();
                search.setParamName(param.getParamName());
                List<PcbMaterialParam> allByLimit = pcbMaterialParamDao.getAllByLimit(search);
                if (allByLimit.stream().count() > 0) {
                    return ResultUtil.error(500, "重复添加", "", null);
                } else {
                    int count = pcbMaterialParamDao.insert(param);
                    if (count > 0) {
                        operateService.addOperate(new Operate(2, Integer.parseInt(userId), "PCB板材参数设置", 1, 1, new Date(), null, JSONObject.toJSONString(param)));
                        return ResultUtil.success(param);
                    }
                    return ResultUtil.error(500, "操作失败", "Operate Fail", null);
                }
            } else {
                PcbMaterialParam oldData = pcbMaterialParamDao.getAllById(param.getPcbMaterialParamId());
                int count = pcbMaterialParamDao.update(param);
                if (count > 0) {
                    operateService.addOperate(new Operate(2, Integer.parseInt(userId), "PCB板材参数设置", 3, 1, new Date(), JSONObject.toJSONString(oldData), JSONObject.toJSONString(param)));
                    return ResultUtil.success(param);
                }
                return ResultUtil.error(500, "操作失败", "Operate Fail", null);
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }

    }

    @Transactional(transactionManager = "MysqlTransactionManager2")
    @Override
    public Result deletePcbMaterialParam(Integer id) {
        try {
            String userId = UserHeaderHolder.getUserId();
            PcbMaterialParam oldData = pcbMaterialParamDao.getAllById(id);
            int count = pcbMaterialParamDao.delete(id);
            if (count > 0) {
                operateService.addOperate(new Operate(2, Integer.parseInt(userId), "PCB板材参数设置", 2, 1, new Date(), JSONObject.toJSONString(oldData), null));
                return ResultUtil.success(null);
            }
            return ResultUtil.error(500, "操作失败", "Operate Fail", null);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Override
    public Result checkPcbMaterialParamHasData(Integer id) {
        PcbMaterialParam pcbMaterialParam = pcbMaterialParamDao.getAllById(id);
        if (pcbMaterialParam != null) {
            String paramKey = pcbMaterialParam.getParamKey();
            PcbMaterialLibrary search = new PcbMaterialLibrary();
            search.setParamKey(paramKey);
            List<PcbMaterialLibrary> allByLimit = pcbMaterialLibraryDao.getAllByLimit(search);
            if (allByLimit.size() > 0) {
                return ResultUtil.success(false);
            } else {
                return ResultUtil.success(true);
            }
        }
        return ResultUtil.success(true);
    }

    @Override
    public List<MaterialInfo> getAllPcbMaterialLibrary(List<PcbMaterialLibrary> params) {//
        List<PcbMaterialLibrary> list;
        List<String> list_rowKey;
        if (params == null) {
            list = pcbMaterialLibraryDao.getAllByLimit(null);
        }
        else {
            List<String> temp = pcbMaterialLibraryDao.getBySearch(params.get(0));
            list_rowKey = temp;
            PcbMaterialParam materialParamLayer = pcbMaterialParamDao.getByParamName("最大层数");
            PcbMaterialParam materialParamThick = pcbMaterialParamDao.getByParamName("最大板厚/mm");
            for (int i = 0; i < params.size(); i++) {
                if(params.get(i).getParamKey().equals(materialParamLayer != null ? materialParamLayer.getParamKey() : " ") ||
                        params.get(i).getParamKey().equals(materialParamThick != null ? materialParamThick.getParamKey() : " "))
                {
                    temp = pcbMaterialLibraryDao.getByParamValueThreshHold(params.get(i).getParamKey(),
                            Double.parseDouble(StringUtils.isBlank(params.get(i).getParamValue()) ? "0" : params.get(i).getParamValue()));
                }else{
                    temp = pcbMaterialLibraryDao.getBySearch(params.get(i));
                }
                list_rowKey.retainAll(temp);
            }
            if (list_rowKey == null || list_rowKey.size() == 0) {
                return null;
            }
            list = pcbMaterialLibraryDao.getByRowKey(list_rowKey);
        }

        Map<String, List<PcbMaterialLibrary>> collect = list.stream().collect(Collectors.groupingBy(PcbMaterialLibrary::getRowKey));
        Map<String, MaterialInfo> materialInfoMap = new HashMap<>();
        List<MaterialVM> sortList0 = new ArrayList<>();
        for (String key : collect.keySet()) {
            List<PcbMaterialLibrary> pcbMaterialData = collect.get(key);
            List<PcbMaterialLibrary> sortList = pcbMaterialData.stream().filter(m -> "input_sort".equals(m.getParamKey())).collect(Collectors.toList());
            if (sortList != null && sortList.size() > 0) {
                sortList0.add(new MaterialVM(key, Integer.parseInt(sortList.get(0).getParamValue())));
            } else {
                sortList0.add(new MaterialVM(key, 999999));
            }
            MaterialInfo materialInfo = new MaterialInfo();
            materialInfo.setPcbMaterialDataList(pcbMaterialData);
            materialInfoMap.put(key, materialInfo);
        }
        Collections.sort(sortList0, new Comparator<MaterialVM>() {
            @Override
            public int compare(MaterialVM p1, MaterialVM p2) {
                return Integer.compare(p1.getOpenStatus(), p2.getOpenStatus());
            }
        });
        List<MaterialInfo> materialInfoList = new ArrayList<>();
        for (int i = 0; i < sortList0.size(); i++) {
            String rowKey = sortList0.get(i).getMaterial();
            MaterialInfo materialInfo = materialInfoMap.get(rowKey);
            materialInfo.setRowKey(rowKey);
            materialInfoList.add(materialInfo);
        }
        return materialInfoList;
    }

    @Transactional(transactionManager = "MysqlTransactionManager2")
    @Override
    public Result insertOrUpdatePcbMaterialLibrary(String data) {
        try {
            String userId = UserHeaderHolder.getUserId();
            JSONObject jsonObject = JSONObject.parseObject(data);
            String mode = jsonObject.getString("mode");
            Integer sort = jsonObject.getInteger("sort");
            Integer sortId = jsonObject.getInteger("sortId");
            JSONArray jsonArray = jsonObject.getJSONArray("pcbTemplateList");
            if (jsonArray == null || jsonArray.size() == 0) {
                return ResultUtil.error(500, "pcbTemplateList 为空", "pcbTemplateList is null", null);
            }

            List<PcbMaterialLibrary> entities = new ArrayList<>();
            String rowKey;
            if (mode.equals("update")) {
                rowKey = jsonObject.getString("rowKey");
            } else {
                rowKey = String.valueOf(System.currentTimeMillis());
            }
            if (sort != null) {
                PcbMaterialLibrary pcbMaterialLibrary = new PcbMaterialLibrary();
                pcbMaterialLibrary.setParamKey("input_sort");
                pcbMaterialLibrary.setParamValue(sort.toString());
                pcbMaterialLibrary.setSort(100);
                pcbMaterialLibrary.setStatus(1);
                pcbMaterialLibrary.setRowKey(rowKey);
                if (sortId == null) {
                    pcbMaterialLibrary.setCreateTime(new Date());
                    int count = pcbMaterialLibraryDao.insert(pcbMaterialLibrary);
                    if (count > 0) {
                        operateService.addOperate(new Operate(2, Integer.parseInt(userId), "PCB板材库", 1, 1, new Date(), null, JSONObject.toJSONString(pcbMaterialLibrary)));
                    } else {
                        return ResultUtil.error(500, "操作失败", "Operate Fail", null);
                    }
                } else {
                    pcbMaterialLibrary.setPcbMaterialLibraryId(sortId);
                    pcbMaterialLibrary.setUpdateTime(new Date());
                    List<PcbMaterialLibrary> oldData = pcbMaterialLibraryDao.getAllById(pcbMaterialLibrary.getPcbMaterialLibraryId());
                    int count = pcbMaterialLibraryDao.update(pcbMaterialLibrary);
                    if (count > 0) {
                        operateService.addOperate(new Operate(2, Integer.parseInt(userId), "PCB板材库", 3, 1, new Date(), JSONObject.toJSONString(oldData), JSONObject.toJSONString(pcbMaterialLibrary)));
                    } else {
                        return ResultUtil.error(500, "操作失败", "Operate Fail", null);
                    }
                }
            }
            for (int i = 0; i < jsonArray.size(); i++) {
                PcbMaterialLibrary pcbMaterialLibrary = new PcbMaterialLibrary();
                JSONObject jo = (JSONObject) jsonArray.get(i);

                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
//                pcbMaterialData.setPcbMaterialDataId(jo.get("pcbMaterialDataId") == null ? null : Integer.parseInt(jo.get("pcbMaterialDataId").toString()));
                pcbMaterialLibrary.setParamKey(jo.get("pcbParamKey") == null ? null : jo.get("pcbParamKey").toString());
                pcbMaterialLibrary.setParamValue(jo.get("pcbParamValue") == null ? null : jo.get("pcbParamValue").toString());
                pcbMaterialLibrary.setSort(jo.get("sort") == null ? null : Integer.parseInt(jo.get("sort").toString()));
                pcbMaterialLibrary.setStatus(jo.get("status") == null ? null : Integer.parseInt(jo.get("status").toString()));


                if (jo.get("pcbMaterialDataId") == null) {
                    pcbMaterialLibrary.setCreateTime(new Date());
                    pcbMaterialLibrary.setRowKey(rowKey);
                    int count = pcbMaterialLibraryDao.insert(pcbMaterialLibrary);
                    if (count > 0) {
                        operateService.addOperate(new Operate(2, Integer.parseInt(userId), "PCB板材库", 1, 1, new Date(), null, JSONObject.toJSONString(pcbMaterialLibrary)));
                    } else {
                        return ResultUtil.error(500, "操作失败", "Operate Fail", null);
                    }

                } else {
                    pcbMaterialLibrary.setPcbMaterialLibraryId(jo.get("pcbMaterialDataId") == null ? null : Integer.parseInt(jo.get("pcbMaterialDataId").toString()));
                    pcbMaterialLibrary.setCreateTime(jo.get("createTime") == null ? null : format.parse(jo.get("createTime").toString()));
                    pcbMaterialLibrary.setUpdateTime(new Date());
                    List<PcbMaterialLibrary> oldData = pcbMaterialLibraryDao.getAllById(pcbMaterialLibrary.getPcbMaterialLibraryId());
                    int count = pcbMaterialLibraryDao.update(pcbMaterialLibrary);
                    if (count > 0) {
                        operateService.addOperate(new Operate(2, Integer.parseInt(userId), "PCB板材库", 3, 1, new Date(), JSONObject.toJSONString(oldData), JSONObject.toJSONString(pcbMaterialLibrary)));
                    } else {
                        return ResultUtil.error(500, "操作失败", "Operate Fail", null);
                    }
                }
                entities.add(pcbMaterialLibrary);
            }

            return ResultUtil.success(entities);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Transactional(transactionManager = "MysqlTransactionManager2")
    @Override
    public Result deletePcbMaterialLibrary(String row_key) {
        try {
            String userId = UserHeaderHolder.getUserId();
            PcbMaterialLibrary search = new PcbMaterialLibrary();
            search.setRowKey(row_key);
            List<PcbMaterialLibrary> oldData = pcbMaterialLibraryDao.getAllByLimit(search);
            int count = pcbMaterialLibraryDao.delete(row_key);
            if (count > 0) {
                operateService.addOperate(new Operate(2, Integer.parseInt(userId), "PCB板材库", 2, 1, new Date(), JSONObject.toJSONString(oldData), null));
                return ResultUtil.success(null);
            } else {
                return ResultUtil.error(500, "操作失败", "Operate Fail", null);
            }
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Transactional(transactionManager = "MysqlTransactionManager2")
    @Override
    public Result updatePcbMaterialFactoryStatus(Integer pcbFactoryMaterialId, String approverId, Integer materialStatus, String remark, Integer openStatus) {
        try {
            String userId = UserHeaderHolder.getUserId();
            PcbMaterialFactory pcbMaterialFactory = pcbMaterialFactoryDao.getById(pcbFactoryMaterialId);
            String oldData = JSONObject.toJSONString(pcbMaterialFactory);
            Integer oldStatus = pcbMaterialFactory.getMaterialStatus();
            int count = pcbMaterialFactoryDao.updateMaterialStatus(pcbFactoryMaterialId, approverId, materialStatus, remark, openStatus);

            if (count > 0) {
                PcbApproveProcess approveProcess = new PcbApproveProcess();
                approveProcess.setApproveType(1);
                approveProcess.setDataId(pcbFactoryMaterialId);
                approveProcess.setApproveUserId(Integer.parseInt(userId));
                approveProcess.setOldStatus(oldStatus.toString());
                approveProcess.setNewStatus(materialStatus.toString());
                approveProcess.setCreateTime(new Date());
                approveProcess.setRemark(remark);
                approveProcessDao.insert(approveProcess);

                PcbMaterialFactory newData = pcbMaterialFactoryDao.getById(pcbFactoryMaterialId);
                operateService.addOperate(new Operate(2, Integer.parseInt(userId), "PCB板厂板材库", 3, 1, new Date(), oldData, JSONObject.toJSONString(newData)));
                return ResultUtil.success(null);
            }
            return ResultUtil.error(500, "操作失败", "Operate Fail", null);
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Override
    public Result getPcbMaterialFileById(Integer id) {
        try {
            PcbMaterialFile pcbMaterialFile = pcbMaterialFileDao.getAllById(id);
            if (pcbMaterialFile != null) {
                String filepath = rootPath + pcbMaterialFile.getFileRelatePath();
                File file = new File(filepath);
                String fname = file.getName();
                byte[] bytedata = null;
                InputStream in = new FileInputStream(file);  //InputStream in = url.openStream();
                bytedata = new byte[in.available()];
                in.read(bytedata);
                in.close();
                Base64.Encoder encoder = Base64.getEncoder();
                String base64 = encoder.encodeToString(bytedata);
                Map<String, Object> map = new HashMap<>();
                map.put("base64", base64);
                map.put("fileName", pcbMaterialFile.getFileName());
                return ResultUtil.success(map);
            } else {
                return ResultUtil.error(500, "没有文件信息", "no file info", null);
            }
        } catch (Exception e) {
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Transactional(transactionManager = "MysqlTransactionManager2")
    @Override
    public Result insertOrUpdatePcbMaterialFactory(String data) {
        try {
            List<PcbMaterialFactory> pcbMaterialFactoryList = new ArrayList<>();
            JSONObject jsonObject = JSONObject.parseObject(data);
            String rowKey = jsonObject.getString("rowKey");
            if (StringUtils.isBlank(rowKey)) {
                return ResultUtil.error(500, "参数rowKey为空", "param rowKey is null", null);
            }
            String userId = UserHeaderHolder.getUserId();
            List<PcbSonFactoryInfo> allFactorys = pcbSonFactoryInfoDao.getAllByLimit(null);
            for (PcbSonFactoryInfo sonFac : allFactorys) {
                Integer sonFacId = sonFac.getPcbSonFactoryId();
                Integer openStatus = jsonObject.getInteger(sonFacId.toString());
                if (openStatus != null) {
                    PcbMaterialFactory pcbMaterialFactory = new PcbMaterialFactory();
                    pcbMaterialFactory.setRowKey(rowKey);
                    pcbMaterialFactory.setFactoryId(sonFacId);
                    pcbMaterialFactory.setOpenStatus(openStatus);
                    pcbMaterialFactory.setStatus(1);
                    pcbMaterialFactory.setSort(100);
                    try {
                        List<PcbMaterialFactory> allByLimit = pcbMaterialFactoryDao.getByLimit(rowKey, sonFacId, null, null, null);
                        if (allByLimit != null && allByLimit.size() > 0) {
                            PcbMaterialFactory old = allByLimit.get(0);
                            String oldData = JSONObject.toJSONString(old);
                            pcbMaterialFactory.setUpdateTime(new Date());
                            int count = pcbMaterialFactoryDao.updateMaterialStatus(old.getPcbFactoryMaterialId(), null, null, null, openStatus);
                            if (count > 0) {
                                String newData = JSONObject.toJSONString(pcbMaterialFactoryDao.getByLimit(rowKey, sonFacId, null, null, null));
                                operateService.addOperate(new Operate(2, Integer.parseInt(userId), "PCB板厂板材库", 3, 1, new Date(), oldData, newData));
                            }
                        } else {
                            pcbMaterialFactory.setMaterialStatus(4);
                            pcbMaterialFactory.setCreateTime(new Date());
                            int count = pcbMaterialFactoryDao.insert(pcbMaterialFactory);
                            if (count > 0) {
                                operateService.addOperate(new Operate(2, Integer.parseInt(userId), "PCB板厂板材库", 1, 1, new Date(), null, JSONObject.toJSONString(pcbMaterialFactory)));
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                        return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
                    }
                    pcbMaterialFactoryList.add(pcbMaterialFactory);
                }
            }
            return ResultUtil.success(null);
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }

    }

    @Transactional(transactionManager = "MysqlTransactionManager2")
    @Override
    public Result insertOrUpdatePcbMaterialLibraryAndFactory(String data) {
        try {
            String userId = UserHeaderHolder.getUserId();
            JSONObject jsonObject = JSONObject.parseObject(data);
            String rowKey = jsonObject.getString("rowKey");
            if (rowKey == null || rowKey.equals("")) {
                return ResultUtil.error(500, "参数rowKey为空", "param rowKey is null", null);
            }
            JSONArray jsonArray = jsonObject.getJSONArray("factoryIds");
            if (jsonArray == null || jsonArray.size() == 0) {
                return ResultUtil.error(500, "参数factoryIds为空", "factoryIds is null", null);
            }
            List<PcbMaterialLibraryAndFactory> list = new ArrayList<>();
            List<String> currentInfo = new ArrayList<>();
            for (int i = 0; i < jsonArray.size(); i++) {
                Integer factoryId = (Integer) jsonArray.get(i);

                PcbMaterialLibraryAndFactory pcbMaterialLibraryAndFactory = new PcbMaterialLibraryAndFactory();
                pcbMaterialLibraryAndFactory.setFactoryId(factoryId);
                pcbMaterialLibraryAndFactory.setRowKey(rowKey);
                List<PcbMaterialLibraryAndFactory> byMaterialIdAndFacoryId = pcbMaterialLibraryAndFactoryDao.getByMaterialIdAndFacoryId(rowKey, factoryId, 1);
                currentInfo.add(rowKey + "-" + factoryId);
                if (byMaterialIdAndFacoryId != null && byMaterialIdAndFacoryId.size() > 0) {
                    continue;
                } else {
                    pcbMaterialLibraryAndFactory.setCreateTime(new Date());
                    pcbMaterialLibraryAndFactory.setStatus(1);
                    pcbMaterialLibraryAndFactory.setSort(100);
                    int count = pcbMaterialLibraryAndFactoryDao.insert(pcbMaterialLibraryAndFactory);
                    if (count > 0) {
                        operateService.addOperate(new Operate(2, Integer.parseInt(userId), "PCB板厂板材关联", 1, 1, new Date(), null, JSONObject.toJSONString(pcbMaterialLibraryAndFactory)));
                    } else {
                        return ResultUtil.error(500, "操作失败", "Operate Fail", null);
                    }

                    PcbMaterialFactory pcbMaterialFactory = new PcbMaterialFactory();
                    pcbMaterialFactory.setPcbMaterialLibraryAndFactoryId(pcbMaterialLibraryAndFactory.getPcbFactoryAndLibraryId());
                    pcbMaterialFactory.setFactoryId(factoryId);
                    pcbMaterialFactory.setRowKey(rowKey);
                    pcbMaterialFactory.setMaterialStatus(DB2Config.materialStatusDraft);
                    pcbMaterialFactory.setCreateTime(new Date());
                    pcbMaterialFactory.setStatus(1);
                    pcbMaterialFactory.setSort(100);
                    count = pcbMaterialFactoryDao.insert(pcbMaterialFactory);
                    if (count > 0) {
                        operateService.addOperate(new Operate(2, Integer.parseInt(userId), "PCB板厂板材库", 1, 1, new Date(), null, JSONObject.toJSONString(pcbMaterialFactory)));
                    } else {
                        return ResultUtil.error(500, "操作失败", "Operate Fail", null);
                    }
                }

                list.add(pcbMaterialLibraryAndFactory);
            }
            List<PcbMaterialLibraryAndFactory> byMaterialIdAndFacoryId = pcbMaterialLibraryAndFactoryDao.getByMaterialIdAndFacoryId(rowKey, null, null);
            for (int i = 0; i < byMaterialIdAndFacoryId.size(); i++) {
                Integer factoryId = byMaterialIdAndFacoryId.get(i).getFactoryId();
                String rowKey2 = byMaterialIdAndFacoryId.get(i).getRowKey();
                Integer dataId = byMaterialIdAndFacoryId.get(i).getPcbFactoryAndLibraryId();

                if (currentInfo.contains(rowKey2 + "-" + factoryId)) {
                    continue;
                } else {
                    PcbMaterialLibraryAndFactory oldData = pcbMaterialLibraryAndFactoryDao.getById(dataId, null);
                    int count = pcbMaterialLibraryAndFactoryDao.deleteById(dataId);
                    if (count > 0) {
                        operateService.addOperate(new Operate(2, Integer.parseInt(userId), "PCB板厂板材关联", 2, 1, new Date(), JSONObject.toJSONString(oldData), null));
                    }

                    List<PcbMaterialFactory> oldData2 = pcbMaterialFactoryDao.getByMaterialLibraryAndFactoryId(dataId);
                    count = pcbMaterialFactoryDao.deleteByMaterialLibraryAndFactoryId(dataId);
                    if (count > 0) {
                        operateService.addOperate(new Operate(2, Integer.parseInt(userId), "PCB板厂板材库", 2, 1, new Date(), JSONObject.toJSONString(oldData2), null));
                    }
                }
            }
            return ResultUtil.success(null);
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }

    }

    @Override
    public List<PcbMaterialLibraryAndFactory> getPcbMaterialLibraryAndFactory(String rowKey) {
        List<PcbMaterialLibraryAndFactory> byMaterialIdAndFacoryId = pcbMaterialLibraryAndFactoryDao.getByMaterialIdAndFacoryId(rowKey, null, 1);
        return byMaterialIdAndFacoryId;
    }

    @Override
    public Result deletePcbMaterialLibraryAndFactory(Integer id) {
        return null;
    }

    @Override
    public List<PcbMaterialFactory> getPcbMaterialAndFactoryData(Integer factoryId, String rowKey, Integer materialStatus, Integer userId) {
        List<PcbMaterialFactory> byMaterialIdAndFacoryId = pcbMaterialFactoryDao.getByLimit(rowKey, factoryId, materialStatus, null, userId);
        for (int i = 0; i < byMaterialIdAndFacoryId.size(); i++) {
            String rowKey2 = byMaterialIdAndFacoryId.get(i).getRowKey();
            PcbMaterialLibrary search = new PcbMaterialLibrary();
            search.setRowKey(rowKey2);
            List<PcbMaterialLibrary> pcbMaterialLibraries = pcbMaterialLibraryDao.getAllByLimit(search);
            byMaterialIdAndFacoryId.get(i).setLibraryList(pcbMaterialLibraries);
            List<PcbMaterialFile> fileList = pcbMaterialFileDao.getAllByRowKey(rowKey2, factoryId);
            byMaterialIdAndFacoryId.get(i).setFileList(fileList);
            String approver = byMaterialIdAndFacoryId.get(i).getApprover();
            if (!StringUtils.isBlank(approver)) {
                List<User> users = new ArrayList<>();
                String[] split = approver.split(",");
                for (int j = 0; j < split.length; j++) {
                    User userInfoById = userDao.getUserInfoById(Integer.parseInt(split[j]));
                    users.add(userInfoById);
                }
                byMaterialIdAndFacoryId.get(i).setApproveUsers(users);
            }
        }
        return byMaterialIdAndFacoryId;
    }

    @Override
    public List<PcbMaterialLibrary> getPcbMaterialData(List<PcbSonFactoryInfo> allFactorys) {
        try {
            final String userId = UserHeaderHolder.getUserId();
            OperateLog operateLog = new OperateLog(2,Integer.parseInt(userId) ,"板材开放能力",4,1,new Date(), UserHeaderHolder.getDomainAccount(), UserHeaderHolder.getIpAddress(), UserHeaderHolder.getNetworkSeg());
            boolean aa = operateLogService.addOperateLog(operateLog);

            PcbMaterialParam search = new PcbMaterialParam();
            search.setParamName("板材");
            List<PcbMaterialParam> bancaiParamList = pcbMaterialParamDao.getAllByLimit(search);
            String paramKey = null;
            if (bancaiParamList != null && bancaiParamList.size() > 0) {
                paramKey = bancaiParamList.get(0).getParamKey();
            } else {
                return null;
            }

            List<PcbMaterialLibrary> bancaiList = pcbMaterialLibraryDao.getMaterial(paramKey);
            Map<String, List<PcbMaterialLibrary>> collect = bancaiList.stream().collect(Collectors.groupingBy(PcbMaterialLibrary::getRowKey));
            Map<String, MaterialInfo> materialInfoMap = new HashMap<>();
            List<MaterialVM> sortList0 = new ArrayList<>();
            for (String key : collect.keySet()) {
                List<PcbMaterialLibrary> pcbMaterialData = collect.get(key);
                List<PcbMaterialLibrary> sortList = pcbMaterialData.stream().filter(m -> "input_sort".equals(m.getParamKey())).collect(Collectors.toList());
                if (sortList != null && sortList.size() > 0) {
                    sortList0.add(new MaterialVM(key, Integer.parseInt(sortList.get(0).getParamValue())));
                } else {
                    sortList0.add(new MaterialVM(key, 999999));
                }
                MaterialInfo materialInfo = new MaterialInfo();
                materialInfo.setPcbMaterialDataList(pcbMaterialData);
                materialInfoMap.put(key, materialInfo);
            }
            Collections.sort(sortList0, new Comparator<MaterialVM>() {
                @Override
                public int compare(MaterialVM p1, MaterialVM p2) {
                    return Integer.compare(p1.getOpenStatus(), p2.getOpenStatus());
                }
            });

            List<PcbMaterialLibrary> bancaiListSort = new ArrayList<>();
            String paramKey2 = paramKey;
            for(int i=0;i<sortList0.size();i++){
                String rowkey =sortList0.get(i).getMaterial();
                final List<PcbMaterialLibrary> pcbMaterialLibraryStream = bancaiList.stream().filter(x -> x.getParamKey().equals(paramKey2) && x.getRowKey().equals(rowkey)).collect(Collectors.toList());
                if(pcbMaterialLibraryStream.size()>0){
                    bancaiListSort.add(pcbMaterialLibraryStream.get(0));
                }
            }

            List<PcbMaterialFactory> bancaiFactoryList = pcbMaterialFactoryDao.getByLimit(null, null, null, null, null);


            Map<String, Integer> map = new HashMap<>();
            for (int i = 0; i < bancaiFactoryList.size(); i++) {
                String key = bancaiFactoryList.get(i).getFactoryId() + "-" + bancaiFactoryList.get(i).getRowKey();
                Integer value = bancaiFactoryList.get(i).getOpenStatus();
                map.put(key, value);
            }
            if (allFactorys == null) {
                allFactorys = pcbSonFactoryInfoDao.getAllByLimit(null);
            }

            for (int i = 0; i < bancaiListSort.size(); i++) {
                String rowKey = bancaiListSort.get(i).getRowKey();
                List<SpecialProcessInfo> factoryOpenStatusList = new ArrayList<>();

                for (int j = 0; j < allFactorys.size(); j++) {
                    Integer factoryId = allFactorys.get(j).getPcbSonFactoryId();
                    if (map.containsKey(factoryId + "-" + rowKey)) {
                        factoryOpenStatusList.add(new SpecialProcessInfo(factoryId, map.get(factoryId + "-" + rowKey)));
                    } else {
                        factoryOpenStatusList.add(new SpecialProcessInfo(factoryId, null));
                    }
                }
                bancaiListSort.get(i).setFactoryOpenStatusList(factoryOpenStatusList);
            }
            return bancaiListSort;
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public List<MaterialVM> getPcbMaterialDataByFactory(PcbSonFactoryInfo pcbSonFactoryInfo) {
        try {
            Integer factoryId = pcbSonFactoryInfo.getPcbSonFactoryId();
            PcbMaterialParam search = new PcbMaterialParam();
            search.setParamName("板材");
            List<PcbMaterialParam> bancaiParamList = pcbMaterialParamDao.getAllByLimit(search);
            String paramKey = "";
            if (bancaiParamList != null && bancaiParamList.size() > 0) {
                paramKey = bancaiParamList.get(0).getParamKey();
            } else {
                return null;
            }
            PcbMaterialLibrary search2 = new PcbMaterialLibrary();
            search2.setParamKey(paramKey);
            List<PcbMaterialFactory> pcbMaterialFactoryList = pcbMaterialFactoryDao.getByLimit(null, factoryId, null, null, null);
            List<MaterialVM> list = new ArrayList<>();
            for (int i = 0; i < pcbMaterialFactoryList.size(); i++) {
                MaterialVM materialVM = new MaterialVM();
                materialVM.setOpenStatus(pcbMaterialFactoryList.get(i).getOpenStatus());
                search2.setRowKey(pcbMaterialFactoryList.get(i).getRowKey());
                List<PcbMaterialLibrary> pcbMaterialLibraryList = pcbMaterialLibraryDao.getAllByLimit(search2);
                if (pcbMaterialLibraryList != null && pcbMaterialLibraryList.size() > 0) {
                    materialVM.setMaterial(pcbMaterialLibraryList.get(0).getParamValue());
                }
                list.add(materialVM);
            }
            return list;
        } catch (Exception e) {
            return null;
        }
    }

    @Transactional(transactionManager = "MysqlTransactionManager2")
    @Override
    public Result addFile(String data) {
        try {
            String userId = UserHeaderHolder.getUserId();
            JSONObject jsonObject = JSONObject.parseObject(data);
            String rowKey = jsonObject.getString("rowKey");
            Integer factoryId = jsonObject.getInteger("factoryId");
            Integer pcbFactoryMaterialId = jsonObject.getInteger("pcbFactoryMaterialId");
            if (pcbFactoryMaterialId == null) {
                return ResultUtil.error(500, "参数pcbFactoryMaterialId为空", "param pcbFactoryMaterialId is null", null);
            }
            if (rowKey == null) {
                return ResultUtil.error(500, "参数rowKey为空", "param rowKey is null", null);
            }
            if (factoryId == null) {
                return ResultUtil.error(500, "参数factoryId为空", "param factoryId is null", null);
            }

            List<PcbMaterialFile> fileList = new ArrayList<>();
            JSONArray jsonArray_file = jsonObject.getJSONArray("fileList");
            if (jsonArray_file != null && jsonArray_file.size() > 0) {
                for (int i = 0; i < jsonArray_file.size(); i++) {
                    JSONObject jo = (JSONObject) jsonArray_file.get(i);
                    PcbMaterialFile pcbMaterialFile = new PcbMaterialFile();
                    pcbMaterialFile.setCreateTime(new Date());
                    String fileName = jo.get("oldName") == null ? null : jo.get("oldName").toString();
                    pcbMaterialFile.setFileName(fileName);
                    Integer fileType = jo.get("fileType") == null ? null : Integer.parseInt(jo.get("fileType").toString());
                    pcbMaterialFile.setFileType(fileType);
                    pcbMaterialFile.setFileRelatePath(jo.get("fileRelatePath") == null ? null : jo.get("fileRelatePath").toString());
                    String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
                    pcbMaterialFile.setFileExtend(ext);
                    pcbMaterialFile.setRowKey(rowKey);
                    pcbMaterialFile.setPcbFactoryId(factoryId);
                    pcbMaterialFile.setPcbMaterialFactoryId(pcbFactoryMaterialId);

                    List<PcbMaterialFile> oldData = pcbMaterialFileDao.getAllByFactoryMaterialId(pcbFactoryMaterialId, fileType);
                    pcbMaterialFileDao.deleteByRowKey(pcbFactoryMaterialId, fileType);
                    int count = pcbMaterialFileDao.insert(pcbMaterialFile);
                    if (count > 0) {
                        operateService.addOperate(new Operate(2, Integer.parseInt(userId), "PCB板材文件", 3, 1, new Date(), JSONObject.toJSONString(oldData), JSONObject.toJSONString(pcbMaterialFile)));
                    }
                    fileList.add(pcbMaterialFile);
                }
            }

            PcbMaterialFactory materialFactory = new PcbMaterialFactory();
            materialFactory.setFactoryId(factoryId);
            materialFactory.setRowKey(rowKey);
            PcbMaterialFactory materialFactory1 = pcbMaterialFactoryDao.getById(pcbFactoryMaterialId);
            String oldData = JSONObject.toJSONString(materialFactory1);
            if (materialFactory1 != null) {
                if (materialFactory1.getMaterialStatus() == (DB2Config.materialStatusApproved)) {
                    materialFactory1.setMaterialStatus(DB2Config.materialStatusDraft);
                    materialFactory1.setUpdateTime(new Date());
                    int count = pcbMaterialFactoryDao.updateMaterialStatus(materialFactory1.getPcbFactoryMaterialId(), materialFactory1.getApprover(), DB2Config.materialStatusDraft, null, null);
                    if (count > 0) {
                        operateService.addOperate(new Operate(2, Integer.parseInt(userId), "PCB板厂板材库", 3, 1, new Date(), oldData, JSONObject.toJSONString(materialFactory1)));
                    }
                }
            }
            return ResultUtil.success(null);
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Override
    public List<CapacityMatch> getCapacityMatch(List<PcbSonFactoryInfo> sonFactoryInfoList, List<PcbMaterialLibrary> requirePcbMaterialLibraryList, Integer requireOpenStatus) {
        List<CapacityMatch> list = new ArrayList<>();
        String requireMaterial = "";

        final PcbMaterialParam pcbMaterialParam = pcbMaterialParamDao.getByParamName("板材");
        if (pcbMaterialParam == null) {
            return list;
        }
        String pcbMaterialParamKey = pcbMaterialParam.getParamKey();
        if (requirePcbMaterialLibraryList != null) {
            for (int i = 0; i < requirePcbMaterialLibraryList.size(); i++) {
                PcbMaterialLibrary param = new PcbMaterialLibrary();
                param.setRowKey(requirePcbMaterialLibraryList.get(i).getRowKey());
                param.setParamKey(pcbMaterialParamKey);
                List<PcbMaterialLibrary> bySearch = pcbMaterialLibraryDao.getAllByLimit(param);
                if (bySearch.size() > 0) {
                    requireMaterial += bySearch.get(0).getParamValue() + ",";
                    requirePcbMaterialLibraryList.get(i).setParamValue(bySearch.get(0).getParamValue());
                }

            }
        }

        for (int i = 0; i < sonFactoryInfoList.size(); i++) {
            Integer pcbSonFactoryId = sonFactoryInfoList.get(i).getPcbSonFactoryId();
            if (requirePcbMaterialLibraryList == null || requirePcbMaterialLibraryList.size() == 0)//无板材要求
            {
                List<PcbMaterialFactory> byLimit = pcbMaterialFactoryDao.getByLimit(null, pcbSonFactoryId, null, null, null);
                String reason = "";
                boolean flag = false;//是否满足
                if (requireOpenStatus != null) {//有开放等级要求
                    for (int j = 0; j < byLimit.size(); j++) {
                        if (byLimit.get(j).getOpenStatus() != null) {
                            if (byLimit.get(j).getOpenStatus() <= requireOpenStatus) {
                                flag = true;
                                break;
                            }
                        }
                    }
                } else//无开放等级要求
                {
                    flag = true;
                }
                CapacityMatch capacityMatch = new CapacityMatch();
                capacityMatch.setPcbSonFactoryInfoId(sonFactoryInfoList.get(i).getPcbSonFactoryId());
                capacityMatch.setParamKey("material");
                capacityMatch.setParamName("板材");
                capacityMatch.setPcbSonFactoryInfo(sonFactoryInfoList.get(i));
                if (flag) {
                    capacityMatch.setIsSatisfied("是");
                } else {
                    capacityMatch.setIsSatisfied("否");
                    reason = "单板损耗管控等级要求为:" + getStrOpenStatus(requireOpenStatus) + ",板厂损耗管控等级不满足;";
                    capacityMatch.setReason(reason);
                }
                list.add(capacityMatch);
            } else {
                boolean flag1 = false;
                boolean flag2 = false;
                String reason1 = "";
                String reason2 = "";

                for (int j = 0; j < requirePcbMaterialLibraryList.size(); j++) {
                    PcbMaterialLibrary pcbMaterialLibrary = requirePcbMaterialLibraryList.get(j);
                    String rowKey = pcbMaterialLibrary.getRowKey();
                    //查询等级，以及板厂数据
                    List<PcbMaterialFactory> factoryDatas = pcbMaterialFactoryDao.getByLimit(rowKey, pcbSonFactoryId, null, null, null);
                    //如果有数据则说明包含该板材
                    if (factoryDatas.size() > 0) {
                        flag2 = true;
                        if (requireOpenStatus != null && requireOpenStatus < factoryDatas.get(0).getOpenStatus()) {
                            reason1 = "单板损耗管控等级要求为:" + getStrOpenStatus(requireOpenStatus) + ",板厂损耗管控等级不满足;";
                        } else {
                            flag1 = true;
                            break;
                        }
                    } else {
                        reason2 = "单板板材要求为:" + requireMaterial + " 板厂无单板要求的板材;";
                    }
                    if (flag1 && flag2) {
                        break;
                    }
                }
                CapacityMatch capacityMatch = new CapacityMatch();
                capacityMatch.setPcbSonFactoryInfoId(sonFactoryInfoList.get(i).getPcbSonFactoryId());
                capacityMatch.setParamKey("material");
                capacityMatch.setParamName("板材");
                capacityMatch.setPcbSonFactoryInfo(sonFactoryInfoList.get(i));
                if (flag1 && flag2) {
                    capacityMatch.setIsSatisfied("是");
                } else {
                    capacityMatch.setIsSatisfied("否");
                    String reason = (!flag1 ? (reason1 + "\r\n") : "") + (!flag2 ? (reason2 + "\r\n") : "");
                    capacityMatch.setReason(reason);
                }
                list.add(capacityMatch);
            }
        }


        return list;
    }

    public String getStrOpenStatus(Integer opS) {
        String str = "";
        if (opS == 1) {
            str = "一级";
        }
        if (opS == 2) {
            str = "二级";
        }
        if (opS == 3) {
            str = "三级";
        }
        if (opS == 4) {
            str = "不开放";
        }
        return str;
    }

    @Override
    public List<PcbMaterialLibrary> getMaterialList() {
//        PcbMaterialParam search = new PcbMaterialParam();
//        search.setParamName("板材");
//        List<PcbMaterialParam> allByLimit = pcbMaterialParamDao.getAllByLimit(search);
//        String paramKey;
//        if (allByLimit != null && allByLimit.size() > 0) {
//            paramKey = allByLimit.get(0).getParamKey();
//            PcbMaterialLibrary pcbMaterialLibrarySearch = new PcbMaterialLibrary();
//            pcbMaterialLibrarySearch.setParamKey(paramKey);
//            return pcbMaterialLibraryDao.getAllByLimit(pcbMaterialLibrarySearch);
//        }
        List<PcbMaterialLibrary> list =  pcbMaterialLibraryDao.getAllByLimit(null);
        if(list == null)
        {
            return null;
        }
        Map<String, List<PcbMaterialLibrary>> collect = list.stream().collect(Collectors.groupingBy(PcbMaterialLibrary::getRowKey));
        List<MaterialVM> sortList0 = new ArrayList<>();
        for (String key : collect.keySet()) {
            List<PcbMaterialLibrary> pcbMaterialData = collect.get(key);
            //根据input_sort的param_key字段值排序sortList0，不存在则设置比较值为999999
            List<PcbMaterialLibrary> sortList = pcbMaterialData.stream().filter(m -> "input_sort".equals(m.getParamKey())).collect(Collectors.toList());
            if (sortList != null && sortList.size() > 0) {
                sortList0.add(new MaterialVM(key, Integer.parseInt(sortList.get(0).getParamValue())));
            } else {
                sortList0.add(new MaterialVM(key, 999999));
            }
        }
        Collections.sort(sortList0, new Comparator<MaterialVM>() {
            @Override
            public int compare(MaterialVM p1, MaterialVM p2) {
                return Integer.compare(p1.getOpenStatus(), p2.getOpenStatus());
            }
        });
        // 根据sortList0的排序结果重排collect
        LinkedHashMap<String, List<PcbMaterialLibrary>> sortedCollect = new LinkedHashMap<>();
        for (MaterialVM materialVM : sortList0) {
            sortedCollect.put(materialVM.getMaterial(), collect.get(materialVM.getMaterial()));
        }
        // 提取 paramKey 为 "板材" 的param_key并组合成一个新列表
        String boardMaterialKey = pcbMaterialParamDao.getByParamName("板材").getParamKey();
        List<PcbMaterialLibrary> boardMaterialKeyElements = new ArrayList<>();
        if(!boardMaterialKey.isEmpty())
        {
            boardMaterialKeyElements = sortedCollect.values().stream()
                    .flatMap(List::stream)
                    .filter(pcbMaterialLibrary -> boardMaterialKey.equals(pcbMaterialLibrary.getParamKey()))
                    .collect(Collectors.toList());
        }

        return boardMaterialKeyElements;
    }
    public List<String> getElectBehaveList() {
        List<PcbMaterialLibrary> list  = pcbMaterialLibraryDao.getAllByLimit(null);
        if(list == null)
        {
            return null;
        }
        Map<String, List<PcbMaterialLibrary>> collect = list.stream().collect(Collectors.groupingBy(PcbMaterialLibrary::getRowKey));
        List<MaterialVM> sortList0 = new ArrayList<>();
        for (String key : collect.keySet()) {
            List<PcbMaterialLibrary> pcbMaterialData = collect.get(key);
            //根据input_sort的param_key字段值排序sortList0，不存在则设置比较值为999999
            List<PcbMaterialLibrary> sortList = pcbMaterialData.stream().filter(m -> "input_sort".equals(m.getParamKey())).collect(Collectors.toList());
            if (sortList != null && sortList.size() > 0) {
                sortList0.add(new MaterialVM(key, Integer.parseInt(sortList.get(0).getParamValue())));
            } else {
                sortList0.add(new MaterialVM(key, 999999));
            }
        }
        Collections.sort(sortList0, new Comparator<MaterialVM>() {
            @Override
            public int compare(MaterialVM p1, MaterialVM p2) {
                return Integer.compare(p1.getOpenStatus(), p2.getOpenStatus());
            }
        });
        // 根据sortList0的排序结果重排collect
        LinkedHashMap<String, List<PcbMaterialLibrary>> sortedCollect = new LinkedHashMap<>();
        for (MaterialVM materialVM : sortList0) {
            sortedCollect.put(materialVM.getMaterial(), collect.get(materialVM.getMaterial()));
        }
        // 提取 paramKey 为 "电气性能等级" 的param_key并组合成一个新列表
        String boardMaterialKey = pcbMaterialParamDao.getByParamName("电气性能等级").getParamKey();
        List<PcbMaterialLibrary> electMaterialKeyElements = new ArrayList<>();
        if(!boardMaterialKey.isEmpty())
        {
            electMaterialKeyElements = sortedCollect.values().stream()
                    .flatMap(List::stream)
                    .filter(pcbMaterialLibrary -> boardMaterialKey.equals(pcbMaterialLibrary.getParamKey()))
                    .collect(Collectors.toList());
        }
        // 去重、过滤空值，并保持顺序
        Set<String> seenValues = new LinkedHashSet<>(); // 用于去重并保持插入顺序

        return electMaterialKeyElements.stream()
                .filter(Objects::nonNull) // 过滤掉 null 对象
                .map(pcb -> pcb.getParamValue()) // 提取 paramValue
                .filter(Objects::nonNull) // 再次过滤掉可能为 null 的 paramValue
                .map(String::trim) // 去除前后空白字符
                .filter(value -> !value.isEmpty()) // 过滤掉空字符串
                .filter(seenValues::add) // 去重同时保持顺序
                .collect(Collectors.toList()); // 收集为 List<String>
    }

    public List<PcbMaterialLibrary> getAllBySearch(String searchK, String searchV){
        return  pcbMaterialLibraryDao.getAllBySearch(searchK, searchV);
    }
    @Override
    public PcbMaterialParam getByParamName(String paramName) {
        return pcbMaterialParamDao.getByParamName(paramName);
    }

    @Override
    public PcbMaterialLibrary getAllByRowKeyAndParamKey(String paramKey, String rowKey) {
        return pcbMaterialLibraryDao.getAllByRowKeyAndParamKey(paramKey, rowKey);
    }

    @Override
    public Result outputPcbMaterialData() {
        try{
            List<PcbMaterialLibrary> pcbMaterialAndFactoryData = getPcbMaterialData(null);
            // 创建工作簿对象
            Workbook workbook = new XSSFWorkbook();
            // 创建工作表对象
            Sheet sheet = workbook.createSheet("Sheet1");
            XSSFCellStyle setBorder = (XSSFCellStyle) workbook.createCellStyle();
            setBorder.setBorderBottom(BorderStyle.THIN);
            setBorder.setBorderLeft(BorderStyle.THIN);
            setBorder.setBorderRight(BorderStyle.THIN);
            setBorder.setBorderTop(BorderStyle.THIN);
            setBorder.setVerticalAlignment(VerticalAlignment.CENTER);
            setBorder.setAlignment(HorizontalAlignment.LEFT);
            //创建字体 加粗
            XSSFFont font = (XSSFFont) workbook.createFont();
            font.setBold(true);
            font.setFontHeight(11);
            setBorder.setFont(font);
            XSSFCellStyle setBorder2 = (XSSFCellStyle) workbook.createCellStyle();
            setBorder2.setBorderBottom(BorderStyle.THIN);
            setBorder2.setBorderLeft(BorderStyle.THIN);
            setBorder2.setBorderRight(BorderStyle.THIN);
            setBorder2.setBorderTop(BorderStyle.THIN);
            setBorder2.setVerticalAlignment(VerticalAlignment.CENTER);
            setBorder2.setAlignment(HorizontalAlignment.LEFT);

            Row rowT1 = sheet.createRow(1);
            Cell cell10 = rowT1.createCell(0);
            cell10.setCellValue("序号");
            Cell cell11 = rowT1.createCell(1);
            cell11.setCellValue("板材");

            Row rowT2 = sheet.createRow(2);
            int columIndex=2;
            List<Integer> pcbFactoryIds_new = new ArrayList<>();
            List<PcbParentFactoryInfo> pcbParentFactoryInfoList = pcbParentFactoryInfoService.getAll(null, null, null, null, null, null, null, null, null, null, null, null, 1, null);
            for (int i = 0; i < pcbParentFactoryInfoList.size(); i++)
            {
                Cell celli = rowT1.createCell(columIndex);
                celli.setCellStyle(setBorder);
                celli.setCellValue(pcbParentFactoryInfoList.get(i).getCompanyName());
                int startIndexT = columIndex;
                List<PcbSonFactoryInfo> sonFactoryInfos = pcbParentFactoryInfoList.get(i).getSonFactoryInfos();
                if (sonFactoryInfos != null && sonFactoryInfos.size() > 0) {
                    for (int j = 0; j < sonFactoryInfos.size(); j++) {
                        Cell cell2j = rowT2.createCell(columIndex);
                        cell2j.setCellValue(sonFactoryInfos.get(j).getSonFactoryName());
                        cell2j.setCellStyle(setBorder);
                        columIndex++;
                        pcbFactoryIds_new.add(sonFactoryInfos.get(j).getPcbSonFactoryId());
                    }
                    CellRangeAddress region3 = new CellRangeAddress(1, 1, startIndexT, columIndex - 1);
                    if (columIndex - 1 > startIndexT) {
                        sheet.addMergedRegion(region3);
                    }
                }
                else {
                    columIndex++;
                    pcbFactoryIds_new.add(-1);
                }
            }

            int rowIndex = 3;
            int seq=1;
            for(int i=0;i<pcbMaterialAndFactoryData.size();i++){
                Row rowi = sheet.createRow(rowIndex);
                rowIndex++;
                Cell celli0= rowi.createCell(0);
                celli0.setCellValue(seq);
                seq++;
                Cell celli1= rowi.createCell(1);
                celli1.setCellValue(pcbMaterialAndFactoryData.get(i).getParamValue());

                List<SpecialProcessInfo> factoryOpenStatusList = pcbMaterialAndFactoryData.get(i).getFactoryOpenStatusList();
                int colIndex2 = 2;
                for (int j = 0; j < pcbFactoryIds_new.size(); j++){
                    Integer fid = pcbFactoryIds_new.get(j);
                    Cell cellij= rowi.createCell(colIndex2);
                    colIndex2++;
                    final List<SpecialProcessInfo> collect = factoryOpenStatusList.stream().filter(x -> x.getFactoryId().equals(fid)).collect(Collectors.toList());
                    if(collect.size()>0){
                        Integer value  = collect.get(0).getSatisfied();
                        if(value!=null){
                            if(value == 1){
                                cellij.setCellValue("I级开放");
                            }
                            if(value == 2){
                                cellij.setCellValue("II级开放");
                            }
                            if(value == 3){
                                cellij.setCellValue("III级开放");
                            }
                            if(value == 4){
                                cellij.setCellValue("不开放");
                            }
                        }
                        else {
                            cellij.setCellValue("");
                        }
                    }
                    else{
                        cellij.setCellValue("");
                    }
                }
            }

            //加边框
            int columnCount = 2 + pcbFactoryIds_new.size();
            for (int i = 3; i <= sheet.getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                for (int j = 0; j < columnCount; j++) {
                    Cell celli = row.getCell(j);
                    if (celli == null) {
                        celli = row.createCell(j);
                        celli.setCellStyle(setBorder2);
                    } else {
                        if (celli.getCellStyle() == null) {
                            celli.setCellStyle(setBorder2);
                        } else {
                            if (celli.getCellStyle().getFillForegroundColor() != IndexedColors.GREEN.getIndex()
                                    && celli.getCellStyle().getFillForegroundColor() != IndexedColors.RED.getIndex()) {
                                celli.setCellStyle(setBorder2);
                            }
                        }
                    }
                }
            }
            for (int i = 1; i <= 2; i++) {
                Row row = sheet.getRow(i);
                for (int j = 0; j < columnCount; j++) {
                    Cell celli = row.getCell(j);
                    if (celli == null) {
                        celli = row.createCell(j);
                        celli.setCellStyle(setBorder);
                    } else {
                        if (celli.getCellStyle() == null) {
                            celli.setCellStyle(setBorder);
                        } else {
                            if (celli.getCellStyle().getFillForegroundColor() != IndexedColors.GREEN.getIndex()
                                    && celli.getCellStyle().getFillForegroundColor() != IndexedColors.RED.getIndex()) {
                                celli.setCellStyle(setBorder);
                            }
                        }
                    }
                }
            }
            //合并单元格
            sheet.addMergedRegion(new CellRangeAddress(1, 2, 0, 0));
            sheet.addMergedRegion(new CellRangeAddress(1, 2, 1, 1));

            sheet.setColumnWidth(0, 15 * 256);
            sheet.setColumnWidth(1, 15 * 256);
            for (int i = 0; i < pcbFactoryIds_new.size() ; i++) {
                sheet.setColumnWidth(2 + i, 12 * 256);
            }

            // 导出Excel文件
            String filename = "板材开放能力数据"+ String.valueOf(System.currentTimeMillis());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String format = sdf.format(new Date());
            String filePath = rootPath + "pcb\\" + format + "\\" + filename + ".xlsx";
            File folder = new File(rootPath + "pcb\\" + format);
            if (!folder.isDirectory()) {
                folder.mkdirs();
            }
            FileOutputStream outputStream = new FileOutputStream(filePath);
            workbook.write(outputStream);
            workbook.close();
            outputStream.close();
            return ResultUtil.success(filePath);
        }
        catch (Exception e){
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }

    }
    /*板材能力导出*/
    public Result outputPcbBoardMaterialAbility() {
        try {

//            final String userId = UserHeaderHolder.getUserId();
//            OperateLog operateLog = new OperateLog(2,Integer.parseInt(userId) ,"板材能力导出",5,1,new Date(),UserHeaderHolder.getDomainAccount(),UserHeaderHolder.getIpAddress(),UserHeaderHolder.getNetworkSeg());
//            boolean aa = operateLogService.addOperateLog(operateLog);
            List<MaterialInfo> allParams =  getAllPcbMaterialLibrary(null);
            Workbook workbook = new XSSFWorkbook();
            // 创建工作表对象
            Sheet sheet = workbook.createSheet("Sheet1");
            XSSFCellStyle setBorder = (XSSFCellStyle) workbook.createCellStyle();
            setBorder.setBorderBottom(BorderStyle.THIN);
            setBorder.setBorderLeft(BorderStyle.THIN);
            setBorder.setBorderRight(BorderStyle.THIN);
            setBorder.setBorderTop(BorderStyle.THIN);

            //创建字体 加粗
            XSSFCellStyle style = (XSSFCellStyle) workbook.createCellStyle();
            XSSFFont font = (XSSFFont) workbook.createFont();
            font.setBold(true);
            font.setFontHeight(11);
            style.setFont(font);
            style.setVerticalAlignment(VerticalAlignment.CENTER);
            setBorder.setFont(font);

            XSSFCellStyle setBorder2 = (XSSFCellStyle) workbook.createCellStyle();
            setBorder2.setBorderBottom(BorderStyle.THIN);
            setBorder2.setBorderLeft(BorderStyle.THIN);
            setBorder2.setBorderRight(BorderStyle.THIN);
            setBorder2.setBorderTop(BorderStyle.THIN);
            XSSFCellStyle dateBoard = (XSSFCellStyle) workbook.createCellStyle();
            dateBoard.setBorderBottom(BorderStyle.THIN);
            dateBoard.setBorderLeft(BorderStyle.THIN);
            dateBoard.setBorderRight(BorderStyle.THIN);
            dateBoard.setBorderTop(BorderStyle.THIN);
            dateBoard.setVerticalAlignment(VerticalAlignment.CENTER);
            dateBoard.setAlignment(HorizontalAlignment.LEFT);
            dateBoard.setDataFormat(workbook.createDataFormat().getFormat("yyyy-MM-dd HH:mm:ss"));

            // 初始化 HashMap
            HashMap<Integer, String> rowIndex2MaterialName = new HashMap<>();
            rowIndex2MaterialName.put(0, "序号");
            rowIndex2MaterialName.put(1, "排序");
            List<PcbMaterialParam> materialParams = pcbMaterialParamDao.getAllByLimit(null);
            if(materialParams == null)
            {
                ResultUtil.error(500, "列表不存在列", "column is null in this page", null);
            }
            // 从数据库获取所有属性名称
            int index = 1;
            for (PcbMaterialParam param : materialParams
                 ) {
                rowIndex2MaterialName.put(++index, param.getParamName());
            }
            for(int j = 0; j < index; j++)
            {
                sheet.setColumnWidth(j, 50 * 256);
            }
            // 设置各个属性名称作为excel列名
            Row row_t1 = sheet.createRow(0);
            for (Map.Entry<Integer, String> entry : rowIndex2MaterialName.entrySet()) {
                int columnIndex = entry.getKey();
                String headerText = entry.getValue();

                Cell cell = row_t1.createCell(columnIndex);
                cell.setCellValue(headerText);
                cell.setCellStyle(setBorder);
            }
            // 更新 HashMap 的值，找到列名称对应的paramKey以备查找
            for (Map.Entry<Integer, String> entry : rowIndex2MaterialName.entrySet()) {
                String paramName = entry.getValue();
                PcbMaterialParam pcbMaterialParam = pcbMaterialParamDao.getByParamName(paramName);
                String paramValue = pcbMaterialParam == null ? null : pcbMaterialParam.getParamKey();
                if (paramValue != null) {
                    rowIndex2MaterialName.put(entry.getKey(), paramValue);
                }
            }
            rowIndex2MaterialName.put(1, "input_sort");
            // 根据paramKey查找对应的属性值填充到excel表中
            for (int i = 0; i < allParams.size(); i++) {
                MaterialInfo info = allParams.get(i);
                Row row = sheet.createRow(i + 1);

                List<PcbMaterialLibrary> libs = info.getPcbMaterialLibraryList();

                Cell celli0 = row.createCell(0);
                celli0.setCellValue(i + 1); // 序号

                for (Map.Entry<Integer, String> entry : rowIndex2MaterialName.entrySet()) {
                    int columnIndex = entry.getKey();
                    if(columnIndex == 0)
                    {
                        continue;
                    }
                    String paramName = entry.getValue();

                    Optional<PcbMaterialLibrary> paramValueOptional = libs.stream()
                            .filter(m -> paramName.equals(m.getParamKey()))
                            .findFirst();

                    if (paramValueOptional.isPresent()) {
                        PcbMaterialLibrary paramValue = paramValueOptional.get();
                        Cell cell = row.createCell(columnIndex);
                        cell.setCellValue(paramValue.getParamValue());
                    }else{
                        Cell cell = row.createCell(columnIndex);
                        cell.setCellValue("");
                    }
                }
            }
            // 导出Excel文件
            String filename = "pcb板材能力" + String.valueOf(System.currentTimeMillis());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String format = sdf.format(new Date());
            File folder = new File(rootPath + "pcb\\" + format);
            if (!folder.isDirectory()) {
                folder.mkdirs();
            }
            String filePath = rootPath + "pcb\\" + format + "\\" + filename + ".xlsx";
            FileOutputStream outputStream = new FileOutputStream(filePath);
            workbook.write(outputStream);
            workbook.close();
            outputStream.close();
            return ResultUtil.success(filePath);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }
    //导出
    @Override
    public Result outputPcbMaterialLibrary() {
        try {

            final String userId = UserHeaderHolder.getUserId();
            OperateLog operateLog = new OperateLog(2,Integer.parseInt(userId) ,"特殊工艺开放能力",5,1,new Date(), UserHeaderHolder.getDomainAccount(), UserHeaderHolder.getIpAddress(), UserHeaderHolder.getNetworkSeg());
            boolean aa = operateLogService.addOperateLog(operateLog);

            List<PcbMaterialLibrary>  allParams = pcbMaterialLibraryDao.getAllByLimit(null);
            Workbook workbook = new XSSFWorkbook();
            // 创建工作表对象
            Sheet sheet = workbook.createSheet("Sheet1");
            XSSFCellStyle setBorder = (XSSFCellStyle) workbook.createCellStyle();
            setBorder.setBorderBottom(BorderStyle.THIN);
            setBorder.setBorderLeft(BorderStyle.THIN);
            setBorder.setBorderRight(BorderStyle.THIN);
            setBorder.setBorderTop(BorderStyle.THIN);

            //创建字体 加粗
            XSSFCellStyle style = (XSSFCellStyle) workbook.createCellStyle();
            XSSFFont font = (XSSFFont) workbook.createFont();
            font.setBold(true);
            font.setFontHeight(11);
            style.setFont(font);
            style.setVerticalAlignment(VerticalAlignment.CENTER);
            setBorder.setFont(font);

            XSSFCellStyle setBorder2 = (XSSFCellStyle) workbook.createCellStyle();
            setBorder2.setBorderBottom(BorderStyle.THIN);
            setBorder2.setBorderLeft(BorderStyle.THIN);
            setBorder2.setBorderRight(BorderStyle.THIN);
            setBorder2.setBorderTop(BorderStyle.THIN);

            Row row_t1 = sheet.createRow(0);
            Cell row_t1Cell = row_t1.createCell(0);
            row_t1Cell.setCellValue("序号");
            row_t1Cell.setCellStyle(setBorder);
            Cell row_t1Cell2 = row_t1.createCell(0);
            row_t1Cell2.setCellValue("排序");
            row_t1Cell2.setCellStyle(setBorder);
            Cell row_t1Cell3 = row_t1.createCell(1);
            row_t1Cell3.setCellValue("板材");
            row_t1Cell3.setCellStyle(setBorder);
            Cell row_t1Cell4 = row_t1.createCell(2);
            row_t1Cell4.setCellValue("电气性能等级");
            row_t1Cell4.setCellStyle(setBorder);
            Cell row_t1Cell5 = row_t1.createCell(2);
            row_t1Cell5.setCellValue("搭配铜箔");
            row_t1Cell5.setCellStyle(setBorder);
            Cell row_t1Cell6 = row_t1.createCell(2);
            row_t1Cell6.setCellValue("低卤属性");
            row_t1Cell6.setCellStyle(setBorder);
            Cell row_t1Cell7 = row_t1.createCell(2);
            row_t1Cell7.setCellValue("发布时间");
            row_t1Cell7.setCellStyle(setBorder);
            Cell row_t1Cell8 = row_t1.createCell(2);
            row_t1Cell8.setCellValue("工艺参数最大层数");
            row_t1Cell8.setCellStyle(setBorder);
            Cell row_t1Cell9 = row_t1.createCell(2);
            row_t1Cell9.setCellValue("多次压合支持");
            row_t1Cell9.setCellStyle(setBorder);
            Cell row_t1Cell10 = row_t1.createCell(2);
            row_t1Cell10.setCellValue("工艺参数最大板厚");
            row_t1Cell10.setCellStyle(setBorder);
            Cell row_t1Cell11 = row_t1.createCell(2);
            row_t1Cell11.setCellValue("最小BGA pitch");
            row_t1Cell11.setCellStyle(setBorder);
            Cell row_t1Cell12 = row_t1.createCell(2);
            row_t1Cell11.setCellValue("道孔成孔孔壁最小间距");
            row_t1Cell11.setCellStyle(setBorder);
            sheet.setColumnWidth(0, 50 * 256);
            sheet.setColumnWidth(1, 50 * 256);
            sheet.setColumnWidth(2, 50 * 256);
            sheet.setColumnWidth(3, 50 * 256);
            sheet.setColumnWidth(4, 50 * 256);
            sheet.setColumnWidth(5, 50 * 256);
            sheet.setColumnWidth(6, 50 * 256);
            sheet.setColumnWidth(7, 50 * 256);
            sheet.setColumnWidth(8, 50 * 256);
            sheet.setColumnWidth(9, 50 * 256);
            sheet.setColumnWidth(10, 50 * 256);
            sheet.setColumnWidth(11, 50 * 256);
            for (int i = 0; i < allParams.size(); i++) {
                Row row = sheet.createRow(i + 1);
                Cell rowCell = row.createCell(0);
                rowCell.setCellStyle(setBorder2);
                Cell rowCell1 = row.createCell(1);
                rowCell1.setCellStyle(setBorder2);
                Cell rowCell2 = row.createCell(2);
                rowCell2.setCellStyle(setBorder2);
            }
            // 导出Excel文件
            String filename = "pcb板材能量管理" + String.valueOf(System.currentTimeMillis());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String format = sdf.format(new Date());
            File folder = new File(rootPath + "pcb\\" + format);
            if (!folder.isDirectory()) {
                folder.mkdirs();
            }
            String filePath = rootPath + "pcb\\" + format + "\\" + filename + ".xlsx";
            FileOutputStream outputStream = new FileOutputStream(filePath);
            workbook.write(outputStream);
            workbook.close();
            outputStream.close();
            return ResultUtil.success(filePath);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

}
